001 /* 002 * Copyright 2005 Stephen J. McConnell 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.tools.tasks; 020 021 import java.io.File; 022 import java.io.OutputStream; 023 import java.io.FileOutputStream; 024 import java.io.OutputStreamWriter; 025 import java.io.Writer; 026 import java.net.URI; 027 028 import net.dpml.lang.Version; 029 030 import net.dpml.library.Module; 031 import net.dpml.library.Resource; 032 import net.dpml.library.Type; 033 034 import net.dpml.transit.Artifact; 035 import net.dpml.transit.link.ArtifactLinkManager; 036 037 import org.apache.tools.ant.BuildException; 038 import org.apache.tools.ant.Project; 039 import org.apache.tools.ant.types.FileSet; 040 import org.apache.tools.ant.taskdefs.Copy; 041 042 /** 043 * Execute the install phase. 044 * 045 * @author <a href="http://www.dpml.net">The Digital Product Meta Library</a> 046 * @version 1.0.0 047 */ 048 public class InstallTask extends GenericTask 049 { 050 /** 051 * Execute the project. 052 * @exception BuildException if a build errror occurs 053 */ 054 public void execute() throws BuildException 055 { 056 installDeliverables(); 057 } 058 059 private void installDeliverables() 060 { 061 Resource resource = getResource(); 062 Type[] types = resource.getTypes(); 063 if( types.length == 0 ) 064 { 065 return; 066 } 067 068 final File deliverables = getContext().getTargetDeliverablesDirectory(); 069 for( int i=0; i < types.length; i++ ) 070 { 071 Type type = types[i]; 072 073 // 074 // Check that the project has actually built the resource 075 // type that it declares 076 // 077 078 String id = type.getID(); 079 String filename = getContext().getLayoutFilename( id ); 080 File group = new File( deliverables, id + "s" ); 081 File target = new File( group, filename ); 082 if( !target.exists() && !id.equalsIgnoreCase( "null" ) ) 083 { 084 final String error = 085 "Project [" 086 + resource 087 + "] declares that it produces the resource type [" 088 + id 089 + "] however no artifacts of that type are present in the target deliverables directory."; 090 throw new BuildException( error, getLocation() ); 091 } 092 093 // 094 // If the type declares an alias then construct a link 095 // and add the link to the deliverables directory as part of 096 // install process. 097 // 098 099 Version version = type.getVersion(); 100 if( null != version ) 101 { 102 try 103 { 104 Artifact artifact = resource.getArtifact( id ); 105 String uri = artifact.toURI().toASCIIString(); 106 107 String link = null; 108 if( Version.NULL_VERSION.equals( version ) ) 109 { 110 link = resource.getName() + "." + id + ".link"; 111 } 112 else 113 { 114 link = resource.getName() 115 + "-" 116 + version.getMajor() 117 + "." 118 + version.getMinor() 119 + "." 120 + id + ".link"; 121 } 122 File out = new File( group, link ); 123 boolean flag = true; 124 if( out.exists() ) 125 { 126 ArtifactLinkManager manager = new ArtifactLinkManager(); 127 URI enclosed = manager.getTargetURI( new URI( out.toURL().toString() ) ); 128 if( artifact.toURI().equals( enclosed ) ) 129 { 130 flag = false; 131 } 132 } 133 134 if( flag ) 135 { 136 log( link.toString() ); 137 log( uri.toString() ); 138 out.createNewFile(); 139 final OutputStream output = new FileOutputStream( out ); 140 final Writer writer = new OutputStreamWriter( output ); 141 writer.write( uri ); 142 writer.close(); 143 output.close(); 144 } 145 } 146 catch( Exception e ) 147 { 148 final String error = 149 "Internal error while attempting to create a link for the resource type [" 150 + id 151 + "] in project [" 152 + resource 153 + "]."; 154 throw new BuildException( error, e, getLocation() ); 155 } 156 } 157 } 158 159 if( deliverables.exists() ) 160 { 161 log( "Installing deliverables from [" + deliverables + "]", Project.MSG_VERBOSE ); 162 final File cache = (File) getProject().getReference( "dpml.cache" ); 163 log( "To cache dir [" + cache + "]", Project.MSG_VERBOSE ); 164 try 165 { 166 final FileSet fileset = new FileSet(); 167 fileset.setProject( getProject() ); 168 fileset.setDir( deliverables ); 169 fileset.createInclude().setName( "**/*" ); 170 Module parent = resource.getParent(); 171 if( null == parent ) 172 { 173 copy( cache, fileset, true ); 174 } 175 else 176 { 177 final String group = parent.getResourcePath(); 178 final File destination = new File( cache, group ); 179 copy( destination, fileset, true ); 180 } 181 } 182 catch( Throwable e ) 183 { 184 final String error = 185 "Unexpected error while constructing ant fileset." 186 + "\nDeliverables dir: " + deliverables; 187 throw new BuildException( error, e ); 188 } 189 } 190 } 191 192 /** 193 * Utility operation to copy a fileset to a destination directory. 194 * @param destination the destination directory 195 * @param fileset the fileset to copy 196 * @param preserve the preserve timestamp flag 197 */ 198 public void copy( final File destination, final FileSet fileset, boolean preserve ) 199 { 200 mkDir( destination ); 201 final Copy copy = (Copy) getProject().createTask( "copy" ); 202 copy.setTaskName( getTaskName() ); 203 copy.setPreserveLastModified( preserve ); 204 copy.setTodir( destination ); 205 copy.addFileset( fileset ); 206 copy.setOverwrite( true ); // required for filtered deliverables 207 copy.init(); 208 copy.execute(); 209 } 210 }